Public Function PointInside(ByVal X As Single, ByVal Y As Single) As Boolean
Dim i As Integer
Dim theta1 As Double
Dim theta2 As Double
Dim dtheta As Double
Dim dx As Double
Dim dy As Double
Dim angles As Double
dx = Points(NumPts).trans(1) - X
dy = Points(NumPts).trans(2) - Y
theta1 = ATan2(CSng(dy), CSng(dx))
If theta1 < 0 Then theta1 = theta1 + 2 * PI
For i = 1 To NumPts
dx = Points(i).trans(1) - X
dy = Points(i).trans(2) - Y
theta2 = ATan2(CSng(dy), CSng(dx))
If theta2 < 0 Then theta2 = theta2 + 2 * PI
dtheta = theta2 - theta1
If dtheta > PI Then dtheta = dtheta - 2 * PI
If dtheta < -PI Then dtheta = dtheta + 2 * PI
angles = angles + dtheta
theta1 = theta2
Next i
PointInside = (Abs(angles) > 0.001)
End Function
' Return True if this polygon is completly above
' the plane containing target.
Public Function IsAbove(ByVal target As Face3d) As Boolean
Dim Nx As Single
Dim Ny As Single
Dim Nz As Single
Dim px As Single
Dim py As Single
Dim pz As Single
Dim dx As Single
Dim dy As Single
Dim dz As Single
Dim Cx As Single
Dim Cy As Single
Dim Cz As Single
Dim i As Integer
' Compute an upward pointing normal to the plane.
target.TransformedNormalVector Nx, Ny, Nz
If Nz < 0 Then
Nx = -Nx
Ny = -Ny
Nz = -Nz
End If
' Get a point on the plane.
target.GetTransformedPoint 1, px, py, pz
' See if the points in this polygon all lie
' above the plane containing target.
For i = 1 To NumPts
' Get the vector from plane to point.
dx = Points(i).trans(1) - px
dy = Points(i).trans(2) - py
dz = Points(i).trans(3) - pz
' If the dot product < 0, the point is
' below the plane.
If dx * Nx + dy * Ny + dz * Nz < -0.01 Then
IsAbove = False
Exit Function
End If
Next i
IsAbove = True
End Function
' Return true if this polygon is completly below
' the plane containing target.
Public Function IsBelow(ByVal target As Face3d) As Boolean
Dim Nx As Single
Dim Ny As Single
Dim Nz As Single
Dim px As Single
Dim py As Single
Dim pz As Single
Dim dx As Single
Dim dy As Single
Dim dz As Single
Dim Cx As Single
Dim Cy As Single
Dim Cz As Single
Dim i As Integer
' Compute a downward pointing normal to the plane.
target.TransformedNormalVector Nx, Ny, Nz
If Nz > 0 Then
Nx = -Nx
Ny = -Ny
Nz = -Nz
End If
' Get a point on the plane.
target.GetTransformedPoint 1, px, py, pz
' See if the points in this polygon all lie
' below the plane containing target.
For i = 1 To NumPts
' Get the vector from plane to point.
dx = Points(i).trans(1) - px
dy = Points(i).trans(2) - py
dz = Points(i).trans(3) - pz
' If the dot product < 0, the point is
' below the plane.
If dx * Nx + dy * Ny + dz * Nz < -0.01 Then
IsBelow = False
Exit Function
End If
Next i
IsBelow = True
End Function
' Return the transformed coordinates of a point
' on the polygon.
Public Sub GetTransformedPoint(ByVal Index As Long, ByRef X As Single, ByRef Y As Single, ByRef Z As Single)
X = Points(Index).trans(1)
Y = Points(Index).trans(2)
Z = Points(Index).trans(3)
End Sub
' Return the bounds of this polygon.
Public Sub GetExtent(ByRef xmin As Single, ByRef xmax As Single, ByRef ymin As Single, ByRef ymax As Single, ByRef zmin As Single, ByRef zmax As Single)
Dim i As Integer
If NumPts < 1 Then Exit Sub
With Points(1)
xmin = .trans(1)
xmax = xmin
ymin = .trans(2)
ymax = ymin
zmin = .trans(3)
zmax = zmin
End With
For i = 2 To NumPts
With Points(i)
If xmin > .trans(1) Then xmin = .trans(1)
If xmax < .trans(1) Then xmax = .trans(1)
If ymin > .trans(2) Then ymin = .trans(2)
If ymax < .trans(2) Then ymax = .trans(2)
If zmin > .trans(3) Then zmin = .trans(3)
If zmax < .trans(3) Then zmax = .trans(3)
End With
Next i
End Sub
' Compute a normal vector for this polygon.
Public Sub NormalVector(ByRef Nx As Single, ByRef Ny As Single, ByRef Nz As Single)
Dim Ax As Single
Dim Ay As Single
Dim Az As Single
Dim Bx As Single
Dim By As Single
Dim Bz As Single
Ax = Points(2).coord(1) - Points(1).coord(1)
Ay = Points(2).coord(2) - Points(1).coord(2)
Az = Points(2).coord(3) - Points(1).coord(3)
Bx = Points(3).coord(1) - Points(2).coord(1)
By = Points(3).coord(2) - Points(2).coord(2)
Bz = Points(3).coord(3) - Points(2).coord(3)
m3Cross Nx, Ny, Nz, Ax, Ay, Az, Bx, By, Bz
End Sub
' Compute a unit normal vector for this polygon.
Public Sub UnitNormalVector(ByRef Nx As Single, ByRef Ny As Single, ByRef Nz As Single)
Dim Length As Single
NormalVector Nx, Ny, Nz
Length = Sqr(Nx * Nx + Ny * Ny + Nz * Nz)
Nx = Nx / Length
Ny = Ny / Length
Nz = Nz / Length
End Sub
' Return the proper shade for this face
' due to the indicated light source.
Private Function SurfaceColor(ByVal light_sources As Collection, ByVal ambient_light As Integer, ByVal eye_x As Single, ByVal eye_y As Single, ByVal eye_z As Single) As Long
' Compute a transformed normal vector for this polygon.
Public Sub TransformedNormalVector(ByRef Nx As Single, ByRef Ny As Single, ByRef Nz As Single)
Dim Ax As Single
Dim Ay As Single
Dim Az As Single
Dim Bx As Single
Dim By As Single
Dim Bz As Single
Ax = Points(2).trans(1) - Points(1).trans(1)
Ay = Points(2).trans(2) - Points(1).trans(2)
Az = Points(2).trans(3) - Points(1).trans(3)
Bx = Points(3).trans(1) - Points(2).trans(1)
By = Points(3).trans(2) - Points(2).trans(2)
Bz = Points(3).trans(3) - Points(2).trans(3)
m3Cross Nx, Ny, Nz, Ax, Ay, Az, Bx, By, Bz
End Sub
' Add one or more points to the polygon.
Public Sub AddPoints(ParamArray coord() As Variant)
Dim num_pts As Integer
Dim i As Integer
Dim pt As Integer
num_pts = (UBound(coord) + 1) \ 3
ReDim Preserve Points(1 To NumPts + num_pts)
pt = 0
For i = 1 To num_pts
Points(NumPts + i).coord(1) = coord(pt)
Points(NumPts + i).coord(2) = coord(pt + 1)
Points(NumPts + i).coord(3) = coord(pt + 2)
Points(NumPts + i).coord(4) = 1#
pt = pt + 3
Next i
NumPts = NumPts + num_pts
End Sub
' Add one or more vertex normals to the polygon.
' Normalize the vectors.
Public Sub AddNormals(ParamArray coord() As Variant)
Dim num_pts As Integer
Dim i As Integer
Dim pt As Integer
Dim X As Single
Dim Y As Single
Dim Z As Single
Dim Length As Single
num_pts = (UBound(coord) + 1) \ 3
ReDim Preserve Normals(1 To NumNormals + num_pts)
pt = 0
For i = 1 To num_pts
X = coord(pt)
Y = coord(pt + 1)
Z = coord(pt + 2)
Length = Sqr(X * X + Y * Y + Z * Z)
Normals(NumNormals + i).coord(1) = X / Length
Normals(NumNormals + i).coord(2) = Y / Length
Normals(NumNormals + i).coord(3) = Z / Length
Normals(NumNormals + i).coord(4) = 1#
pt = pt + 3
Next i
NumNormals = NumNormals + num_pts
End Sub
' Apply a transformation matrix which may not
' contain 0, 0, 0, 1 in the last column to the
' object.
Public Sub ApplyFull(M() As Single)
Dim i As Integer
' Do nothing if we are culled.
If IsCulled Then Exit Sub
For i = 1 To NumPts
m3ApplyFull Points(i).coord, M, Points(i).trans
Next i
End Sub
' Apply a transformation matrix to the object.
Public Sub Apply(M() As Single)
Dim i As Integer
' Do nothing if we are culled.
If IsCulled Then Exit Sub
For i = 1 To NumPts
m3Apply Points(i).coord, M, Points(i).trans
Next i
End Sub
' Draw the transformed points on a Form, Printer,
' or PictureBox.
Public Sub Draw(ByVal pic As PictureBox, ByVal light_sources As Collection, ByVal ambient_light As Integer, ByVal eye_x As Single, ByVal eye_y As Single, ByVal eye_z As Single)